package com.wonders.hisdoctor.station.project.medicine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wonders.his.common.exception.CustomException;
import com.wonders.his.common.service.project.drugs.service.IDrugConfigurationService;
import com.wonders.his.common.service.project.drugs.vo.DrugConfiguration;
import com.wonders.his.framework.utils.oracle.IdUtils;
import com.wonders.hisdoctor.station.constant.ServiceConstant;
import com.wonders.hisdoctor.station.enums.ItemClassEnum;
import com.wonders.hisdoctor.station.enums.OracleSequenceEnum;
import com.wonders.hisdoctor.station.project.base.domain.OutpCipherPresc;
import com.wonders.hisdoctor.station.project.base.domain.OutpCipherPrescDetail;
import com.wonders.hisdoctor.station.project.base.domain.OutpPresc;
import com.wonders.hisdoctor.station.project.base.mapper.OutpCipherPrescDetailMapper;
import com.wonders.hisdoctor.station.project.base.mapper.OutpCipherPrescMapper;
import com.wonders.hisdoctor.station.project.medicine.mapper.CipherPrescMapper;
import com.wonders.hisdoctor.station.project.medicine.service.ICipherPrescSerive;
import com.wonders.hisdoctor.station.project.medicine.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author 张澎_9970
 * @date 2021.2.28 下午 6:40 星期日
 * @desc: 协定处方_Impl
 */
@Service
public class CipherPrescSeriveImpl implements ICipherPrescSerive {

    @Autowired
    private CipherPrescMapper cipherPrescMapper;

    @Autowired
    private IdUtils idUtils;

    @Autowired
    private OutpCipherPrescMapper outpCipherPrescMapper;

    @Autowired
    private OutpCipherPrescDetailMapper outpCipherPrescDetailMapper;

    @Autowired
    private IDrugConfigurationService drugConfigurationService;

    /**
     * 转方_校验
     *
     * @param list 转方_list
     * @return List<CipherDateVo>
     */
    @Override
    public CipherQuoteVO cipherCheck(List<CipherPrescDetailVO> list, String patientId) {
        // 引用
        CipherQuoteVO cipherQuoteVO = new CipherQuoteVO();
        // 处方_list
        List<CipherPresVO> presList = new ArrayList<>();
        // 详情_list
        List<CipherPrescDetailVO> details;
        //Map
        HashMap<String, List<CipherPrescDetailVO>> prescNoMap = new HashMap<>(5);
        // msg 去重map
        final HashMap<String, String> map = new HashMap<>(5);
        StringBuilder msgBuilder = new StringBuilder();
        for (CipherPrescDetailVO detail : list) {
            // 获取过期时间
            DrugConfiguration drugConfiguration = drugConfigurationService.getDrugConfiguration();
            Integer expireRangeDays = drugConfiguration.getExpireRangeDays();
            // 总库存
            Double totalInventory = cipherPrescMapper.cipherCheck(detail, expireRangeDays);
            if (totalInventory == 0.0 && !map.containsKey(detail.getDrugCode())) {
                map.put(detail.getDrugCode(), detail.getDrugName());
                msgBuilder.append("[").append(detail.getDrugName()).append(" ").append(detail.getDrugSpec()).append("], 库存不足或已下架.<br/>");
            } else {
                // 冻结库存
                Double freezeInventory = cipherPrescMapper.getFrozenQuantity(detail);
                // 可用数量
                double availableInventory = totalInventory - freezeInventory;
                // 单位
                String units = detail.getUnits();
                if (availableInventory < detail.getAmount().intValue() && !map.containsKey(detail.getDrugCode())) {
                    map.put(detail.getDrugCode(), detail.getDrugName());
                    msgBuilder.append(detail.getDrugName()).append(", 库存:[").append(availableInventory).append("]").append(units).append(", 库存不足!<br/>");
                } else {
                    // 处方号
                    String prescNo = detail.getPrescNo();
                    // 判断是否有该处方号
                    if (!prescNoMap.containsKey(prescNo)) {
                        details = new ArrayList<>();
                        prescNoMap.put(prescNo, details);
                    }
                    prescNoMap.get(prescNo).add(detail);
                }
            }
        }
        Set<String> keys = prescNoMap.keySet();
        // 二次for循环, 整理层级结构
        for (String prescNo : keys) {
            CipherPresVO presVO = new CipherPresVO();
            presVO.setPrescNo(prescNo);
            List<CipherPrescDetailVO> detailVOList = prescNoMap.get(prescNo);
            presVO.setDetailList(detailVOList);
            presVO.setNumber(detailVOList.size());
            presList.add(presVO);
        }
        cipherQuoteVO.setMessage(msgBuilder.toString());
        cipherQuoteVO.setPrescList(presList);
        return cipherQuoteVO;
    }

    /**
     * 校验处方是否重复
     * TODO, 待删除, 2021年6月17日
     *
     * @param detail
     */
    private String checkRepeat(OutpCipherPrescDetail detail, String patientId) {
        // 转方明细中的字段值
        String code = detail.getDrugCode();
        String spec = detail.getDrugSpec();
        Date date = new Date();

        // 查已有处方
        List<OutpPresc> outpPrescs = cipherPrescMapper.getPrescs(patientId, code, spec, date);
        if (CollectionUtils.isEmpty(outpPrescs)) {
            return "";
        }
        for (OutpPresc outpPresc : outpPrescs) {
            String drugCode = outpPresc.getDrugCode();
            String drugSpec = outpPresc.getDrugSpec();
            Date visitDate = outpPresc.getVisitDate();
            String drugName = outpPresc.getDrugName();
            Integer chargeIndicator = outpPresc.getChargeIndicator();
            // 判断今天是否已开药
            if (code.equals(drugCode)
                    && spec.equals(drugSpec)
                    && 0 == chargeIndicator
                    && new Date().equals(visitDate)) {
                throw new CustomException(drugName + ", 今日已开药!");
            }
            // 判断过去的药还够吃几天
            if (code.equals(drugCode)
                    && spec.equals(drugSpec)
                    && 2 == chargeIndicator) {
                Integer days = outpPresc.getPrescDuration();
                // 吃完的日期
                Date finishedDate = org.apache.commons.lang3.time.DateUtils.addDays(visitDate, days);
                if (finishedDate.after(new Date())) {
                    long finish = finishedDate.getTime();
                    long today = date.getTime();
                    int enoughDays = (int) ((finish - today) / (1000 * 60 * 60 * 24));
                    return "[" + drugName + "]还够" + enoughDays + "天的量, 是否继续开药 ?";
                }
            }
        }
        return "";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveAs(CiperPrescVo ciperPrescVo) {
        Long cipherId = idUtils.getNextVal(OracleSequenceEnum.SEQ_OUTP_CIPHER_PRESC.getCode());
        Long cipherDetailId = outpCipherPrescDetailMapper.getMaxId();

        // 协定处方主表
        OutpCipherPresc outpCipherPresc = ciperPrescVo.getOutpCipherPresc();
        outpCipherPresc.setCipherId(cipherId);
        outpCipherPresc.setCreateTime(new Date());
        outpCipherPrescMapper.insert(outpCipherPresc);

        // 协定处方明细表
        List<OutpCipherPrescDetail> outpCipherPrescDetails = ciperPrescVo.getOutpCipherPrescDetails();
        int i = 0;
        for (; i < outpCipherPrescDetails.size(); i++) {
            outpCipherPrescDetails.get(i).setCipherId(cipherId);
            outpCipherPrescDetails.get(i).setCipherDetailId(cipherDetailId + i + 1);
            outpCipherPrescDetailMapper.insert(outpCipherPrescDetails.get(i));
        }
        return i;
    }

    @Override
    public List<OutpCipherPrescVo> qryCipherPresc(QryCipherPrescVO qryCipherPrescVO) {
        return cipherPrescMapper.qryCipherPresc(qryCipherPrescVO);
    }

    /**
     * 协定处方_查询_下列表
     *
     * @param cipherId 协定处方ID
     * @return List<CipherPrescDetailVo>
     */
    @Override
    public List<CipherPrescDetailVO> queryCipherPrescDetail(String cipherId) {
        List<CipherPrescDetailVO> list = cipherPrescMapper.queryCipherPrescDetail(cipherId);
        Map<String, Integer> map = new HashMap<>(9);
        int num = 0;
        for (CipherPrescDetailVO cipherPrescDetailVO : list) {
            String prescNo = cipherPrescDetailVO.getPrescNo();
            num = !map.containsKey(prescNo) ? 1 : ++num;
            map.put(prescNo, num);
            if (cipherPrescDetailVO.getItemClass().equals(ItemClassEnum.CHINESE_MEDICINE.getCode())) {
                String[] arr = cipherPrescDetailVO.getMeno().split(",");
                cipherPrescDetailVO.setHerbUsage(arr[0] + arr[1] + arr[2] + "，" + arr[3] + "，" + arr[4] + arr[5] + "。");
            }
        }
        for (CipherPrescDetailVO vo : list) {
            vo.setNumber(map.get(vo.getPrescNo()));
        }
        return list;
    }

    /**
     * 协定处方_删除
     *
     * @param cipherId 协定处方ID
     * @param empNo    医生编号
     * @return Integer
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer delete(String cipherId, String empNo) {
        QueryWrapper<OutpCipherPresc> wrapper = new QueryWrapper<>();
        wrapper.eq(ServiceConstant.CIPHER_ID, cipherId).eq(ServiceConstant.OWNER, empNo);
        if (outpCipherPrescMapper.delete(wrapper) != 1) {
            return 0;
        }
        QueryWrapper<OutpCipherPrescDetail> detailWrapper = new QueryWrapper<>();
        detailWrapper.eq(ServiceConstant.CIPHER_ID, cipherId);
        return outpCipherPrescDetailMapper.delete(detailWrapper);
    }
}
